package io.potato.ts.service;

import io.potato.core.AppException;
import io.potato.core.util.AssertUtils;
import io.potato.core.util.SmsUtil;
import io.potato.core.util.StringUtils;
import io.potato.ts.common.Constants;
import io.potato.ts.common.model.SmsSendParam;
import io.potato.ts.domain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 网页发送短信服务
 * author: timl
 * time: 2019-4-12 10:06
 */
@Service
@Transactional
public class WebSmsService {

    @Autowired
    private UserService userService;

    @Autowired
    private ContactsService contactsService;

    @Autowired
    private UserGroupService userGroupService;

    @Autowired
    private MobileFileService mobileFileService;

    @Autowired
    private SmsSendingRecordService ssrService;

    @Autowired
    private SmsSendedRecordService sendedRecordService;

    @Autowired
    private SmsService smsService;

    /**
     * 提交单条短信
     * @param userCode  用户
     * @param mobile  接收号码
     * @param content  短信内容
     */
    public void submitSms(String userCode, String mobile, String content) {
        AssertUtils.isNotBlank(mobile, "手机号码不能为空");
        AssertUtils.isNotBlank(content, "短信内容不能为空");

        if (!SmsUtil.isPhoneNumber(mobile)) {
            throw new AppException("手机号码格式不正确");
        }

        SmsSendingRecord record = ssrService.newWebSmsRecord(userCode, userCode,
                content, mobile, userCode, Constants.SmsType.NORMAL, LocalDateTime.now());
        smsService.submitBatchSms(userCode, Arrays.asList(record));
    }

    /**
     * 提交短信发送任务
     * @param sendParam  发送短信参数
     */
    public void submitSms(Integer userId, SmsSendParam sendParam) {
        AssertUtils.isNotNull(sendParam);
        AssertUtils.isNotBlank(sendParam.getContent(), "短信内容不能为空");

        User user = checkAndGetUser(userId);

        // 接收人号码
        Set<String> numbers = getNumerList(user, sendParam);

        if (numbers.isEmpty()) {
            throw new AppException("短信接收号码不能为空");
        }

        String content = processContent(sendParam, user);
        String userCode = user.getUserCode();
        String extendCode = sendParam.isAddAccountInfo() ? userCode : "";
        String taskName = sendParam.getTaskName() == null ? userCode : sendParam.getTaskName();

        LocalDateTime sendTime = sendParam.getSendTime() == null ? LocalDateTime.now() : sendParam.getSendTime();
        Integer smsType = sendParam.getSendTime() != null && sendParam.getSendTime().isAfter(LocalDateTime.now()) ? Constants.SmsType.SCHEDULE : Constants.SmsType.NORMAL;

        List<SmsSendingRecord> sendingList = new ArrayList<>();

        for (String number : numbers) {
            SmsSendingRecord record = ssrService.newWebSmsRecord(userCode, extendCode, content, number, taskName, smsType, sendTime);
            sendingList.add(record);
        }

        smsService.submitBatchSms(user.getUserCode(), sendingList);
    }

    /**
     * 重发短信
     * @param sendedRecId 短信记录ID
     */
    public void sendAgain(Integer userId, Long sendedRecId) {
        Optional<SmsSendedRecord> optionalRecord = sendedRecordService.findById(sendedRecId);
        if (!optionalRecord.isPresent()) {
            return;
        }
        SmsSendedRecord rec = optionalRecord.get();

        SmsSendingRecord record = ssrService.newWebSmsRecord(
                rec.getUserCode(), rec.getExtendCode(), rec.getContent(),
                rec.getDestNum(), "重发短信", Constants.SmsType.NORMAL, LocalDateTime.now());

        smsService.submitBatchSms(rec.getUserCode(), Arrays.asList(record));
    }

    /**
     * 统计接收号码个数（会去重）
     * @param sendParam 接收号码参数
     * @return  接收号码个数
     */
    public int countSms(User user, SmsSendParam sendParam) {
        Set<String> numbers = getNumerList(user, sendParam);
        return numbers.size();
    }

    /**
     * 查询号码列表
     * @param user
     * @param sendParam
     * @return
     */
    private Set<String> getNumerList(User user, SmsSendParam sendParam) {
        Set<String> numbers = new HashSet<>();

        // 个人通讯录号码
        List<Contacts> contactsList = contactsService.findList(user.getId(), sendParam.getContactsGroupIdList(), null);
        contactsList.forEach(c -> addNumber(numbers, c.getMobileNo()));

        // 共享通讯录号码
        List<Contacts> shareContactsList = contactsService.findShareList(user.getOrganId(), sendParam.getShareContactsGroupIdList(), null);
        shareContactsList.forEach(c -> addNumber(numbers, c.getMobileNo()));

        // 用户组号码
        List<User> userList = userGroupService.findUser(sendParam.getUserGroupIdList(), user.getOrganId());
        userList.forEach(u -> addNumber(numbers, u.getMobileNo()));

        // 号码文件
        Set<String> nums = getMobileFileNumbers(sendParam.getMobileFileIdList(), user.getId());
        numbers.addAll(nums);

        // 号码
        if (sendParam.getNumberList() != null) {
            for (String number : sendParam.getNumberList()) {
                addNumber(numbers, number);
            }
        }

        return numbers;
    }

    private void addNumber(Set<String> numSet, String num) {
        if (StringUtils.isBlank(num)) {
            return;
        }
        if (SmsUtil.isPhoneNumber(num)) {
            numSet.add(num);
        }
    }

    private Set<String> getMobileFileNumbers(List<Integer> ids, Integer userId) {
        Set<String> numbers = new HashSet<>();
        List<MobileFile> list = mobileFileService.findByIds(ids, userId);
        if (!list.isEmpty()) {
            for (MobileFile file : list) {
                String[] arr = file.getNums().split(" ");
                for (String num : arr) {
                    addNumber(numbers, num);
                }
            }
        }
        return numbers;
    }

    private User checkAndGetUser(Integer userId) {
        Optional<User> optionalUser = userService.findById(userId);
        if (!optionalUser.isPresent()) {
            throw new AppException("用户不存在");
        }

        User user = optionalUser.get();

        if (user.getLocked() > 0) {
            throw new AppException("用户已锁定");
        }
        return user;
    }

    private String processContent(SmsSendParam sendParam, User user) {
        String content = sendParam.getContent().trim();
        if (sendParam.isNeedReply()) {
            content += "(收到请回)";
        }

        if (sendParam.isAddName()) {
            content += "[" +user.getRealName() + "]";
        }
        return content;
    }

}
